package com.baize.filedowndemo.autoupdate

import android.annotation.SuppressLint
import android.annotation.TargetApi
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.*
import android.util.Log
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import com.baize.filedowndemo.OkDownloadManager
import com.baize.filedowndemo.R
import com.liulishuo.okdownload.DownloadTask
import com.liulishuo.okdownload.core.cause.EndCause
import com.liulishuo.okdownload.core.cause.ResumeFailedCause
import com.liulishuo.okdownload.core.listener.DownloadListener3
import com.liulishuo.okdownload.core.listener.assist.Listener1Assist
import java.io.File
import java.lang.Exception
import java.util.concurrent.atomic.AtomicBoolean

@SuppressLint("RemoteViewLayout")
class UpgradeService : Service() {
  //版本升级通知id
  val UPGRADE_NOTIFY_ID = 1

  private val mBinder = DownloadBinder()

  private val remoteViews: RemoteViews by lazy {
    RemoteViews(packageName, R.layout.service_download_progress)
  }

  //下载状态
  val downloading = AtomicBoolean(false)

  lateinit var mHandler: Handler

  val downloadListener = object : DownloadListener3() {
    override fun retry(task: DownloadTask, cause: ResumeFailedCause) {
    }

    override fun connected(
      task: DownloadTask, blockCount: Int, currentOffset: Long, totalLength: Long
    ) {
    }

    override fun progress(task: DownloadTask, currentOffset: Long, totalLength: Long) {
      val progress = (100f * currentOffset / totalLength).toInt()
      mBinder.listener?.onProgressChange(progress)
      updateDefaultNotification("下载中...", progress)
    }

    override fun started(task: DownloadTask) {
      downloading.set(true)
    }

    override fun taskEnd(
      task: DownloadTask,
      cause: EndCause,
      realCause: Exception?,
      model: Listener1Assist.Listener1Model
    ) {
      super.taskEnd(task, cause, realCause, model)
      downloading.set(false)
    }

    override fun completed(task: DownloadTask) {
      mBinder.listener?.downloadFinish(true, task.file, null)
      updateDefaultNotification("下载完成!", 100)
      stopSelf()
    }

    override fun canceled(task: DownloadTask) {
      mBinder.listener?.downloadFinish(false, task.file, "取消下载")
    }

    override fun error(task: DownloadTask, e: Exception) {
      mBinder.listener?.downloadFinish(false, task.file, "${e.message}")
      updateDefaultNotification("错误：${e.message}", 0)
    }

    override fun warn(task: DownloadTask) {
      mBinder.listener?.downloadFinish(true, task.file, null)
    }
  }

  override fun onBind(intent: Intent) = mBinder

  class DownloadBinder : Binder() {
    var listener: UpgradeServiceListener? = null

    fun setUpgradeServiceListener(listener: UpgradeServiceListener) {
      Log.d("baize_", "getProgress...")
      this.listener = listener
    }

    fun downloadFinish(success: Boolean, errorReason: String?) {
      Log.d("baize_", "downloadFinish...")
    }
  }

  //Service创建时调用
  override fun onCreate() {
    super.onCreate()
    Log.i("baize_", "onCreate: ")
    mHandler = Handler(Looper.getMainLooper())
    setForegroundService() //开始下载
  }

  //Service每次启动时调用
  override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    Log.i("baize_", "onStartCommand: ")
    if (!downloading.get()) {
      val apkName = intent?.getStringExtra("APK_NAME") ?: "dodo.apk"
      Log.i("baize_", "onStartCommand: 开始真正下载...${apkName}")
      val task = OkDownloadManager.createDownloadTask(DOWNLOAD_APK_URL to apkName)
      task.enqueue(downloadListener)
    }
    return super.onStartCommand(intent, flags, startId)
  }

  /**
   * 通过通知启动前台服务
   */
  private fun setForegroundService() { //    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    val notification = UpgradeServiceHelper.getUpgradeNotify(this, remoteViews)
    startForeground(UPGRADE_NOTIFY_ID, notification)
  }

  private fun updateDefaultNotification(downloadState: String, progress: Int) {
    remoteViews.setTextViewText(R.id.tv_state, downloadState)
    remoteViews.setProgressBar(R.id.progressbar, 100, progress, false)
    val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
    manager.notify(UPGRADE_NOTIFY_ID, UpgradeServiceHelper.getUpgradeNotify(this, remoteViews))
  }


  override fun onDestroy() {
    super.onDestroy()
    Log.i("baize_", "Service onDestroy: ")
  }

  /**
   * 帮助类
   */
  class UpgradeServiceHelper {

    companion object {

      fun getUpgradeNotify(context: Context, remoteViews: RemoteViews): Notification {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
          val channelId = UpgradeConstance.DEFAULT_CHANNEL_ID
          val channelName = UpgradeConstance.DEFAULT_CHANNEL_NAME
          val channelDescription = UpgradeConstance.DEFAULT_CHANNEL_DESCRIPTION
          createNotificationChannel(
            context,
            channelId,
            channelName,
            NotificationManager.IMPORTANCE_DEFAULT,
            channelDescription
          )
        }
        val notification: Notification =
          NotificationCompat.Builder(context, "default") //        .setContentTitle("自动更新")
            //        .setContentText("下载apk中...")
            .setWhen(System.currentTimeMillis())
            .setSmallIcon(R.drawable.ic_launcher_foreground) //        .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.ic_launcher_background))
            .setCustomContentView(remoteViews).setCustomBigContentView(remoteViews).setOngoing(true)
            .build()
        return notification
      }

      @TargetApi(Build.VERSION_CODES.O)
      private fun createNotificationChannel(
        context: Context,
        channelId: String,
        channelName: String,
        importance: Int,
        description: String? = null
      ) {
        val channel = NotificationChannel(channelId, channelName, importance)
        description?.let {
          channel.description = description
        }
        channel.setShowBadge(false)
        val notificationManager =
          context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
      }
    }
  }

  interface UpgradeServiceListener {
    fun onProgressChange(progress: Int)
    fun downloadFinish(isSuccess: Boolean, filePath: File?, errReason: String?)
  }
}

